package com.da.common.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;

/**
 * @Author: hyacinth
 * @CreateTime: 2025-01-13
 * @Version: 1.0
 */

public class TimestampUtil {

    /**
     * 默认的日期时间格式：yyyy-MM-dd HH:mm:ss
     */
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    /**
     * 默认的日期格式：yyyy-MM-dd
     */
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";

    /**
     * 默认的时间格式：HH:mm:ss
     */
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    /**
     * 获取当前时间
     *
     * @return 当前时间的 Date 对象
     */
    public static Date now() {
        return new Date();
    }

    /**
     *  根据指定的毫秒时间戳生成 Date 对象
     *
     * @param timestamp 毫秒时间戳
     * @return 根据毫秒时间戳创建的 Date 对象
     */
    public static Date fromTimestamp(long timestamp){
        return new Date(timestamp);
    }

    /**
     *  将 Date 对象格式化为指定格式的字符串
     *
     * @param date      要格式化的 Date 对象
     * @param formatStr 格式化字符串
     * @return 格式化后的日期字符串
     */
    public static String format(Date date, String formatStr) {
        if(Objects.isNull(date)){
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
        return sdf.format(date);
    }

    /**
     *  将 Date 对象格式化为默认格式的字符串 yyyy-MM-dd HH:mm:ss
     *
     * @param date 要格式化的 Date 对象
     * @return 格式化后的日期字符串
     */
    public static String format(Date date) {
        return format(date, DEFAULT_DATE_TIME_FORMAT);
    }

    /**
     * 将日期字符串解析为 Date 对象
     *
     * @param dateStr  要解析的日期字符串
     * @param formatStr  格式化字符串
     * @return 解析后的 Date 对象
     * @throws ParseException 如果解析失败
     */
    public static Date parse(String dateStr, String formatStr) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
        return sdf.parse(dateStr);
    }

    /**
     * 将日期字符串解析为 Date 对象，使用默认格式yyyy-MM-dd HH:mm:ss
     *
     * @param dateStr 要解析的日期字符串
     * @return 解析后的 Date 对象
     * @throws ParseException 如果解析失败
     */
    public static Date parse(String dateStr) throws ParseException{
        return parse(dateStr, DEFAULT_DATE_TIME_FORMAT);
    }

    /**
     *  在 Date 对象上添加指定的时间量
     *
     * @param date       要操作的 Date 对象
     * @param calendarField Calendar 中定义的时间字段，例如 Calendar.YEAR, Calendar.MONTH, Calendar.DATE
     * @param amount     要添加的数量，可以是负数
     * @return 添加时间后的 Date 对象
     */
    public static Date add(Date date, int calendarField, int amount) {
        if(Objects.isNull(date)){
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(calendarField, amount);
        return calendar.getTime();
    }

    /**
     * 在 Date 对象上添加指定的年份
     *
     * @param date   要操作的 Date 对象
     * @param amount 要添加的年数，可以是负数
     * @return 添加年份后的 Date 对象
     */
    public static Date addYear(Date date, int amount){
        return add(date, Calendar.YEAR, amount);
    }

    /**
     * 在 Date 对象上添加指定的月份
     *
     * @param date   要操作的 Date 对象
     * @param amount 要添加的月数，可以是负数
     * @return 添加月份后的 Date 对象
     */
    public static Date addMonth(Date date, int amount){
        return add(date, Calendar.MONTH, amount);
    }

    /**
     * 在 Date 对象上添加指定的天数
     *
     * @param date   要操作的 Date 对象
     * @param amount 要添加的天数，可以是负数
     * @return 添加天数后的 Date 对象
     */
    public static Date addDate(Date date, int amount){
        return add(date, Calendar.DATE, amount);
    }

    /**
     * 在 Date 对象上添加指定的小时
     *
     * @param date   要操作的 Date 对象
     * @param amount 要添加的小时，可以是负数
     * @return 添加小时后的 Date 对象
     */
    public static Date addHour(Date date, int amount){
        return add(date, Calendar.HOUR, amount);
    }

    /**
     * 在 Date 对象上添加指定的分钟
     *
     * @param date   要操作的 Date 对象
     * @param amount 要添加的分钟，可以是负数
     * @return 添加分钟后的 Date 对象
     */
    public static Date addMinute(Date date, int amount){
        return add(date, Calendar.MINUTE, amount);
    }

    /**
     * 在 Date 对象上添加指定的秒
     *
     * @param date   要操作的 Date 对象
     * @param amount 要添加的秒数，可以是负数
     * @return 添加秒数后的 Date 对象
     */
    public static Date addSecond(Date date, int amount){
        return add(date, Calendar.SECOND, amount);
    }

    /**
     * 获取指定 Date 对象的年份
     *
     * @param date 要操作的 Date 对象
     * @return 年份
     */
    public static int getYear(Date date){
        if(Objects.isNull(date)){
            throw new IllegalArgumentException("date cannot be null");
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 获取指定 Date 对象的月份
     *
     * @param date 要操作的 Date 对象
     * @return 月份 (1-12)
     */
    public static int getMonth(Date date){
        if(Objects.isNull(date)){
            throw new IllegalArgumentException("date cannot be null");
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取指定 Date 对象的天
     *
     * @param date 要操作的 Date 对象
     * @return 天 (1-31)
     */
    public static int getDay(Date date){
        if(Objects.isNull(date)){
            throw new IllegalArgumentException("date cannot be null");
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DATE);
    }

    /**
     *  获取指定 Date 对象的小时
     *
     * @param date 要操作的 Date 对象
     * @return 小时 (0-23)
     */
    public static int getHour(Date date){
        if(Objects.isNull(date)){
            throw new IllegalArgumentException("date cannot be null");
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    /**
     *  获取指定 Date 对象的分钟
     *
     * @param date 要操作的 Date 对象
     * @return 分钟 (0-59)
     */
    public static int getMinute(Date date){
        if(Objects.isNull(date)){
            throw new IllegalArgumentException("date cannot be null");
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MINUTE);
    }

    /**
     *  获取指定 Date 对象的秒
     *
     * @param date 要操作的 Date 对象
     * @return 秒 (0-59)
     */
    public static int getSecond(Date date){
        if(Objects.isNull(date)){
            throw new IllegalArgumentException("date cannot be null");
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.SECOND);
    }

    /**
     * 将 Date 转换为 LocalDateTime
     * @param date
     * @return
     */
    public static LocalDateTime toLocalDateTime(Date date){
        if (Objects.isNull(date)) {
            return null;
        }
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    /**
     * 将 LocalDateTime 转换为 Date
     * @param localDateTime
     * @return
     */
    public static Date toDate(LocalDateTime localDateTime){
        if(Objects.isNull(localDateTime)){
            return null;
        }
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取当前日期，格式为 yyyy-MM-dd
     *
     * @return 当前日期字符串，例如：2023-10-26
     */
    public static String getCurrentDate() {
        return LocalDate.now().format(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT));
    }

    /**
     * 获取当前日期时间，格式为 yyyy-MM-dd HH:mm:ss
     * @return 当前日期时间字符串，例如：2023-10-26 15:30:45
     */
    public static String getCurrentDateTime(){
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT));
    }

    /**
     * 获取当前时间，格式为 HH:mm:ss
     * @return 当前时间字符串，例如 15:30:45
     */
    public static String getCurrentTime(){
        return LocalTime.now().format(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT));
    }

}
